package com.cskaoyan.exception;

import com.cskaoyan.bean.common.BaseRespVo;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ValidationException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 捕捉Controller层的Handle方法出现的异常并进行处理
 *
 * @author zhuqiushi
 * @since 2022/09/08 14:31
 */
@RestControllerAdvice
public class ExceptionControllerAdvice {
    //对使用valid进行参数校验的Handler抛出的异常进行处理
    //当使用@NotBlank注解时跳到这里
    @ExceptionHandler(ValidationException.class)
    public BaseRespVo validationException(ValidationException exception) {
        String message = exception.getMessage();
        return BaseRespVo.invalidParameter(message);
    }

    //这里捕捉所有空指针异常
    @ExceptionHandler(NullPointerException.class)
    public BaseRespVo nullPointerException(NullPointerException exception) {
        String message = exception.getMessage();
        return BaseRespVo.invalidParameter(message);
    }


    @ExceptionHandler(AuthenticationException.class)
    public BaseRespVo authenticationException(AuthenticationException exception) {
        BaseRespVo baseRespVo = new BaseRespVo();
            baseRespVo.setErrno(605);
            baseRespVo.setErrmsg("账户和密码不匹配");
            return baseRespVo;
    }

    @ExceptionHandler(AuthorizationException.class)
    public BaseRespVo authorizationException(AuthorizationException exception) {
        BaseRespVo baseRespVo = new BaseRespVo();
        baseRespVo.setErrno(605);
        baseRespVo.setErrmsg("你没有权限访问");
        return baseRespVo;
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public BaseRespVo validationErrorHandler(MethodArgumentNotValidException ex) {
        // 同样是获取BindingResult对象，然后获取其中的错误信息
        // 如果前面开启了fail_fast，事实上这里只会有一个信息
        //如果没有，则可能又多个
        List<String> errorInformation = ex.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        return BaseRespVo.invalidParameter(errorInformation.get(0).toString());
    }

}
